package com.rockcent.job.task;

import com.rockcent.common.domain.enumclass.Whether;
import com.rockcent.common.utils.DateFormatUtils;
import com.rockcent.common.utils.DateUtils;
import com.rockcent.helper.MallMemberHelper;
import com.rockcent.mall.lib.domain.*;
import com.rockcent.mall.lib.domain.enumclass.MallMemberFundTransactionType;
import com.rockcent.mall.lib.domain.enumclass.MallMemberRechargeType;
import com.rockcent.mall.lib.domain.enumclass.MallMemberStatus;
import com.rockcent.mall.lib.repository.*;
import com.rockcent.service.MallMemberSrv;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * Created by hone on 17-3-9.
 */
@Component
public class MallServiceFeeTask {

    final Logger log = LoggerFactory.getLogger(MallServiceFeeTask.class);

    @Autowired
    private MallMemberSrv mallMemberSrv;

    @Autowired
    private MallMemberBaseServiceFeeFlowRepository mallMemberBaseServiceFeeFlowRepository;

    @Autowired
    private MallMemberMerchantServiceFeeFlowRepository mallMemberMerchantServiceFeeFlowRepository;

    @Autowired
    private MallMemberTransactionCommissionFlowRepository mallMemberTransactionCommissionFlowRepository;

    @Autowired
    private MallMemberPayStandardRepository mallMemberPayStandardRepository;

    @Autowired
    private MallMemberRepository mallMemberRepository;

    private static final String DAY = "01";

    /**
     * 扣减平台基础服务费
     * 0 0 1 1 * ? 每月1日01:00触发
     * 0 0 3 * * ? 每天凌晨3:00执行任务
     */
    @Scheduled(cron = "${job.baseServiceFee.cron}")
    @Transactional(propagation = Propagation.REQUIRED)
    public void deductionBaseServiceFee() {
        String currentDay = getDay();
        if(StringUtils.isNotEmpty(currentDay) && currentDay.equals(DAY)) {
            String endDate = DateUtils.getLastMonthLastDay();
//        String endDate = DateUtils.getCurrentMonthLastDay();//测试使用
        List<MallMember> mallMemberList = getMallMembers();
            if (mallMemberList != null && mallMemberList.size() > 0) {
                for (MallMember mallMember : mallMemberList) {
                    Date effectDate = mallMember.getEffectDate();
                    if(effectDate==null) {
                        continue;
                    }
                    String effectDateStr = DateUtils.date2String(effectDate,DateFormatUtils.DATE_FORMAT1);
                    boolean isFirst = checkFirst(effectDateStr,endDate);
                    //查询平台付费标准
                    MallMemberPayStandard mallMemberPayStandard = getMallMemberPayStandard(mallMember.getMallId(), mallMember.getId());
                    if (mallMemberPayStandard == null) {
                        continue;
                    }
                    //基础服务费
                    BigDecimal baseServiceFee = mallMemberPayStandard.getBaseServiceFee();
                    //基础服务费系数
                    String feeNum = mallMemberPayStandard.getBaseServiceFeeNum();
                    if (baseServiceFee == null || StringUtils.isEmpty(feeNum)) {
                        continue;
                    }
                    BigDecimal baseServiceFeeNum = new BigDecimal(feeNum);
                    BigDecimal baseFee = baseServiceFee.multiply(baseServiceFeeNum);
                    if(isFirst) {
                        int day = DateUtils.compareDate(effectDateStr,endDate,0)+1;
                        baseFee = baseFee.multiply(new BigDecimal(day)).divide(BigDecimal.valueOf(30), 2, BigDecimal.ROUND_HALF_UP);
                    }
                    MallMemberBaseServiceFeeFlow mallMemberBaseServiceFeeFlow = new MallMemberBaseServiceFeeFlow();
                    //生成流水号
                    String seqNo = MallMemberHelper.SINGLETON.createRechargeSeqNo(MallMemberRechargeType.BASE_SERVICE_PAYMENTS);
                    String msg = "{\"baseServiceFee\":"+baseServiceFee+",\"baseServiceFeeNum\":"+baseServiceFeeNum+",\"desc\":\"扣减平台基础服务费流水\"}";
                    mallMemberBaseServiceFeeFlow.setSeqNo(seqNo);
                    mallMemberBaseServiceFeeFlow.setAmount(baseFee);
                    mallMemberBaseServiceFeeFlow.setMallId(mallMember.getMallId());
                    mallMemberBaseServiceFeeFlow.setMallMemberId(mallMember.getId());
                    mallMemberBaseServiceFeeFlow.setRemark(msg);
                    mallMemberBaseServiceFeeFlow.setBaseServiceFeeNum(feeNum);
                    mallMemberBaseServiceFeeFlow.setSettlementDate(DateUtils.getCurrentTime());
                    mallMemberBaseServiceFeeFlowRepository.save(mallMemberBaseServiceFeeFlow);
                    mallMemberSrv.changeMallMemberFund(baseFee,mallMember.getId(), MallMemberFundTransactionType.BASE_SERVICE_PAYMENTS,seqNo);
                }
//                log.info("======================>成功扣减基础服务费的平台数量:{}",mallMemberList.size());
            }
        }
    }

    /**
     * 扣减平台下的商户服务费
     */
    @Scheduled(cron = "${job.merchantServiceFee.cron}")
    @Transactional(propagation = Propagation.REQUIRED)
    public void deductionMerchantServiceFee() {
        String currentDay = getDay();
        if(StringUtils.isNotEmpty(currentDay) && currentDay.equals(DAY)) {
            List<MallMember> mallMemberList = getMallMembers();
            if (mallMemberList != null && mallMemberList.size() > 0) {
                for (MallMember mallMember : mallMemberList) {
                    //查询平台付费标准
                    MallMemberPayStandard mallMemberPayStandard = getMallMemberPayStandard(mallMember.getMallId(), mallMember.getId());
                    if (mallMemberPayStandard == null) {
                        continue;
                    }
                    BigDecimal businessServiceFee = mallMemberPayStandard.getBusinessServiceFee();
                    String feeNum = mallMemberPayStandard.getBusinessServiceFeeNum();
                    if (businessServiceFee == null || StringUtils.isEmpty(feeNum)) {
                        continue;
                    }
                    BigDecimal businessServiceFeeNum = new BigDecimal(feeNum);
                    BigDecimal businessFee = businessServiceFee.multiply(businessServiceFeeNum);
                    List<Long> mallMembers = mallMemberPayStandardRepository.compulateMallMerchantsCount(mallMember.getMallId(),null,null);
                    int mallMemberCount = mallMembers==null?0:mallMembers.size();
                    String memberIds = "";
                    if(mallMemberCount>0) {
                        memberIds=StringUtils.join(mallMembers,",");
                    }
                    BigDecimal membersCount = new BigDecimal(mallMemberCount);
                    BigDecimal fee = businessFee.multiply(membersCount);
                    String msg = "{\"businessServiceFee\":"+businessServiceFee+",\"memberIds\":\""+memberIds+"\",\"businessServiceFeeNum\":"+businessServiceFeeNum+",\"desc\":\"扣减平台商户服务费流水\"}";
                    MallMemberMerchantServiceFeeFlow flow = new MallMemberMerchantServiceFeeFlow();
                    //生成流水号
                    String seqNo = MallMemberHelper.SINGLETON.createRechargeSeqNo(MallMemberRechargeType.MERCHANT_SERVICE_PAYMENTS);
                    flow.setAmount(fee);
                    flow.setMallId(mallMember.getMallId());
                    flow.setMallMemberId(mallMember.getId());
                    flow.setSeqNo(seqNo);
                    flow.setRemark(msg);
                    flow.setSettlementDate(DateUtils.getCurrentTime());
                    flow.setMerchantCounts(mallMemberCount);
                    flow.setBusinessServiceFeeNum(feeNum);
                    flow.setBusinessServiceFee(businessServiceFee);
                    mallMemberMerchantServiceFeeFlowRepository.save(flow);
                    mallMemberSrv.changeMallMemberFund(fee,mallMember.getId(), MallMemberFundTransactionType.MERCHANT_SERVICE_PAYMENTS,seqNo);
                }
//                log.info("======================>成功扣减商户服务费的平台数量:{}",mallMemberList.size());
            }
        }
    }

    /**
     * 扣减平台下的交易佣金
     */
    @Scheduled(cron = "${job.transactionFee.cron}")
    @Transactional(propagation = Propagation.REQUIRED)
    public void deductionTransactionFee() {
        String currentDay = getDay();
        if(StringUtils.isNotEmpty(currentDay) && currentDay.equals(DAY)) {
            String startDate = DateUtils.getLastMonthFirstDay();
            String endDate = DateUtils.getLastMonthLastDay();
//            String startDate = DateUtils.getCurrentMonthFirstDay();//测试使用
//            String endDate = DateUtils.getCurrentMonthLastDay();//测试使用
            List<MallMember> mallMemberList = getMallMembers();
            if (mallMemberList != null && mallMemberList.size() > 0) {
                for (MallMember mallMember : mallMemberList) {
                    Date effectDate = mallMember.getEffectDate();
                    if(effectDate==null) {
                        continue;
                    }
                    String effectDateStr = DateUtils.date2String(effectDate,DateFormatUtils.DATE_FORMAT1);
                    boolean isFirst = checkFirst(effectDateStr,endDate);
                    startDate = isFirst==true?effectDateStr:startDate;
                    //查询平台付费标准
                    MallMemberPayStandard mallMemberPayStandard = getMallMemberPayStandard(mallMember.getMallId(), mallMember.getId());
                    if (mallMemberPayStandard == null) {
                        continue;
                    }
                    String dealResellRate = mallMemberPayStandard.getDealResellRate();
                    if(StringUtils.isEmpty(dealResellRate)) {
                        continue;
                    }
                    List<Long> mallMembers = mallMemberPayStandardRepository.compulateMallMerchantsCount(mallMember.getMallId(),null,null);
                    Double verifyAmount=new Double(0);
                    String memberIds="";
                    if(mallMembers!=null && mallMembers.size()>0) {
                        memberIds=StringUtils.join(mallMembers,",");
                        verifyAmount = mallMemberPayStandardRepository.compulateMallMerchantsAmount(mallMember.getMallId(), mallMembers, startDate+" 00:00:00", endDate+" 23:59:59");
                    }
                    verifyAmount = verifyAmount==null?new Double(0):verifyAmount;
                    BigDecimal amount = new BigDecimal(verifyAmount);
                    BigDecimal rate = new BigDecimal(dealResellRate);
                    BigDecimal totalAmount = amount.multiply(rate);
                    String msg = "{\"amount\":"+amount+",\"memberIds\":\""+memberIds+"\",\"rate\":"+rate+",\"desc\":\"扣减平台交易佣金流水\"}";
                    //生成流水号
                    String seqNo = MallMemberHelper.SINGLETON.createRechargeSeqNo(MallMemberRechargeType.MALL_EXCHANGE);
                    MallMemberTransactionCommissionFlow flow = new MallMemberTransactionCommissionFlow();
                    flow.setAmount(totalAmount);
                    flow.setMallId(mallMember.getMallId());
                    flow.setMallMemberId(mallMember.getId());
                    flow.setSeqNo(seqNo);
                    flow.setRemark(msg);
                    flow.setSettlementDate(DateUtils.getCurrentTime());
                    flow.setTransactionAmount(amount);
                    flow.setCommissionRate(rate);
                    mallMemberTransactionCommissionFlowRepository.save(flow);
                    mallMemberSrv.changeMallMemberFund(totalAmount,mallMember.getId(), MallMemberFundTransactionType.MALL_EXCHANGE,seqNo);
                }
//                log.info("======================>成功扣减交易佣金的平台数量:{}",mallMemberList.size());
            }
        }
    }

    /**
     * 是否是首次
     * @param effectDate
     * @param lastDate
     * @return
     */
    private boolean checkFirst(String effectDate, String lastDate) {
        boolean result = false;
        int effectDateYear = DateUtils.getCurrentYear(effectDate);
        int effectDateMonth = DateUtils.getCurrentMonth(effectDate);
        int lastDateYear = DateUtils.getCurrentYear(lastDate);
        int lastDateMonth = DateUtils.getCurrentMonth(lastDate);
        if(effectDateYear==lastDateYear && effectDateMonth==lastDateMonth) {
            result=true;
        }
        return result;
    }

    /**
     * 查询平台付费标准
     * @param mallId
     * @param mallMemberId
     * @return
     */
    private MallMemberPayStandard getMallMemberPayStandard(Long mallId, Long mallMemberId) {
        return mallMemberPayStandardRepository.findByMallIdAndMallMemberIdAndIsDelete(mallId, mallMemberId, Whether.NO);
    }

    /**
     * 获取会员账号
     * @return
     */
    private List<MallMember> getMallMembers() {
        return mallMemberRepository.findByStatusAndIsDelete(MallMemberStatus.MEMBER,Whether.NO);
    }

    /**
     * 获取当前几号
     * @return
     * @throws Exception
     */
    private String getDay() {
        //获取当前日期
        String currentDate = DateUtils.getCurrentTime(DateFormatUtils.DATE_FORMAT1);
        //找出几号
        String currentDay = currentDate.substring(8,currentDate.length());
        return currentDay;
    }
}